﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;

namespace mbine.msgc.model
{
    public sealed class CRoster
    {
        static CRoster instance = null;
        public bool IsLoginProc = true;
        public List<CUser> Users { get; set; }
        public List<CPart> Parts { get; set; }
        static readonly object padlock = new object();

        public event EventHandler EventRosterChanged;

        CRoster()
        {
            Users = new List<CUser>();
            Parts = new List<CPart>();
        }

        public static CRoster Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new CRoster();
                    }
                    return instance;
                }
            }
        }

        /// <summary>
        /// Roster 정보를 받을 경우 처리
        /// </summary>
        /// <param name="_s"></param>
        public void SetRoster(string _s)
        {
            List<CRosterUser> list = JsonConvert.DeserializeObject<List<CRosterUser>>(_s);
            foreach (CRosterUser u in list)
                SetUserStatus(u.email, int.Parse(u.status));

            if (EventRosterChanged != null)
                EventRosterChanged(this, null);

            IsLoginProc = false;
        }

        /// <summary>
        /// 인증 서버에서 사용자 정보를 받음(초기 로그인시에 동작함.)
        /// </summary>
        /// <param name="_s"></param>
        public void Set(string _s)
        {
            IsLoginProc = true;

            Users.Clear();
            Parts.Clear();
            Parts.Add(new CPart { Name = "친구", Key = "0", IsCustom = true, Order = 0, PartCode = ""});

            Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(_s);

            List<object> objPart = JsonConvert.DeserializeObject<List<object>>(dict["part"].ToString());
            List<object> objUser = JsonConvert.DeserializeObject<List<object>>(dict["user"].ToString());

            //부서 Assign
            foreach (object s in objPart)
            {
                Dictionary<string, string> v = JsonConvert.DeserializeObject<Dictionary<string, string>>(s.ToString());
                Parts.Add(new CPart { Name = v["Name"], Key = v["Code"], IsCustom = false, Order = 0, PartCode = v["PartCode"] });
            }

            //하위 부서들에 대한 Assign
            foreach (CPart p in Parts)
            {
                CPart part = (CPart)FindPart(p.PartCode);
                if(part != null)
                    part.Parts.Add(p);
            }

            //사용자 Assign
            foreach (object s in objUser)
            {
                Dictionary<string, string> v = JsonConvert.DeserializeObject<Dictionary<string, string>>(s.ToString());
                CPart part = (CPart)FindPart(v["PartCode"]);
                CUser u = new CUser { Name = v["Name"], Email = v["Email"], Part = part };
                Users.Add(u);
                if (part != null)
                    part.Users.Add(u);
            }
        }

        public string GetRosterJson()
        {
            return JsonConvert.SerializeObject(
                (from u in Users where u.Email != CCUser.Instance.Email select u.Email).ToArray()
                , Formatting.None);
        }

        private IPart FindPart(string _key)
        {
            return Parts.Find(part => part.Key == _key);
        }

        public IUser GetUser(string _email)
        {
            foreach (IUser u in Users)
            {
                if (((CUser)u).Email == _email)
                    return u;
            }
            return null;
        }

        /// <summary>
        /// 특정 사용자의 상태값을 변경한다.
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="_status"></param>
        private void SetUserStatus(string _id, int _status)
        {
            foreach (IUser u in Users)
            {
                if (((CUser)u).Email == _id)
                {
                    ((CUser)u).Status.Code = _status;
                    return;
                }
            }
        }

        public List<IUser> GetUserByStatus(CStatus _status)
        {
            List<IUser> r = new List<IUser>();
            foreach (IUser u in Users)
            {
                if (((CUser)u).Status.Code == _status.Code)
                    r.Add(u);
            }
            return r;
        }
    }
}
